package com.peanutplan.blog.interceptor;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.peanutplan.blog.annotation.SynchronizeToEs;
import com.peanutplan.blog.model.vo.ContentEsVo;
import com.peanutplan.blog.model.vo.ContentVo;
import com.peanutplan.blog.utils.DateUtil;
import com.peanutplan.blog.utils.ElasticSearchUtils;
import com.peanutplan.blog.utils.SensitiveWordUtil;
import com.vdurmont.emoji.EmojiParser;

/**
 * 用来同步文章，暂时只考虑标题和内容~
 * @author Administrator
 *
 */
@Aspect
@Component
public class ArticleSynchronizeToEsAspect {
	
	@Autowired
	private SensitiveWordUtil sensitiveWordUtil;
	
	@Pointcut("@annotation(com.peanutplan.blog.annotation.SynchronizeToEs)")
    public void annotationPoinCut(){}
	
	@After("annotationPoinCut()")
    public void after(JoinPoint joinPoint) throws NoSuchMethodException, SecurityException{
        String methodName=joinPoint.getSignature().getName();
        Class<?> classTarget=joinPoint.getTarget().getClass();
        Class<?>[] par=((MethodSignature) joinPoint.getSignature()).getParameterTypes();
        Method objMethod=classTarget.getMethod(methodName, par);

        SynchronizeToEs action = objMethod.getAnnotation(SynchronizeToEs.class);
        Map<String, Object> allArgs = getNameAndValue(joinPoint);
        
        //需要同步到哪个索引
        String index = action.esIndex();
        //需要同步哪个参数
        String paramName = action.paramName();
        //需要操作的类型，更新创建还是删除
        String type = action.type();
        
        //添加
        if(type.equals("create")) {
        	ContentVo article = (ContentVo) allArgs.get(paramName);
        	if(article.getCid()!=null) {
        		article.setCreated(DateUtil.getCurrentUnixTime());
        		
        		article.setContent(EmojiParser.parseToAliases(article.getContent()));
        		article.setContent(sensitiveWordUtil.replaceSensitiveWord(article.getContent()));
        		article.setContentText(sensitiveWordUtil.replaceSensitiveWord(article.getContentText()));
        		article.setRemark(sensitiveWordUtil.replaceSensitiveWord(article.getRemark()));

        		
	        	ContentEsVo entity = new ContentEsVo(article);
	        	ElasticSearchUtils.addEntityDoc(index, entity.getCid().toString(), entity);
        	}
        	
        }
        
        //添加
        if(type.equals("update")) {
        	ContentVo article = (ContentVo) allArgs.get(paramName);
        	if(article.getCid()!=null && article.getContent()!=null) {
        		
        		article.setContent(EmojiParser.parseToAliases(article.getContent()));
        		article.setContent(sensitiveWordUtil.replaceSensitiveWord(article.getContent()));
        		article.setContentText(sensitiveWordUtil.replaceSensitiveWord(article.getContentText()));
        		article.setRemark(sensitiveWordUtil.replaceSensitiveWord(article.getRemark()));

        		
	        	ContentEsVo entity = new ContentEsVo(article);
	        	ElasticSearchUtils.upSertById(index, entity.getCid().toString(), entity);
        	}
        }
        
        //添加
        if(type.equals("delete")) {
        	Integer cid = (Integer) allArgs.get(paramName);
        	ElasticSearchUtils.deleteDocById(index, cid.toString());
        }
        
	}
	
	/**
     * 获取参数Map集合
     * @param joinPoint
     * @return
     */
    Map<String, Object> getNameAndValue(JoinPoint joinPoint) {
        Map<String, Object> param = new HashMap<>();
 
        Object[] paramValues = joinPoint.getArgs();

        String[] paramNames = ((MethodSignature)joinPoint.getSignature()).getParameterNames(); // 参数名
 
         for (int i = 0; i < paramNames.length; i++) {
            param.put(paramNames[i], paramValues[i]);
        }
 
        return param;
    }
}
